package com.meshnetics.gb.stack.mac.primitives;

import com.meshnetics.gb.stack.core.event.StackEventType;
import com.meshnetics.gb.stack.core.event.StackResponse;
import com.meshnetics.gb.stack.mac.RadioMACStackLayer;
import com.meshnetics.gb.type.impl.ByteUtils;
import com.meshnetics.gb.type.impl.zcl.*;

import java.nio.ByteBuffer;

/**
 * WRITE DESCRIPTION HERE
 *
 * @author AKovylin
 */
public class MACOrphanResponse extends StackResponse implements MACCommand, MACReplyAwaited {
    public static final byte CODE = 0x53;

    private final UInt orphanAddress;
    private final UInt shortAddress;
    private final Bool associatedMember;
    private final Bool securityEnable;

    public MACOrphanResponse(long orphanAddress, short shortAddress, boolean associatedMember, boolean securityEnable) {
        this(new Long(orphanAddress), new Short(shortAddress),
                Boolean.valueOf(associatedMember), Boolean.valueOf(securityEnable));
    }

    public MACOrphanResponse(Long orphanAddress, Short shortAddress, Boolean associatedMember, Boolean securityEnable) {
        this((UInt) TypeUInt.UINT_64.fromObject(orphanAddress),
                (UInt) TypeUInt.UINT_16.fromObject(shortAddress),
                (Bool) TypeBool.BOOLEAN.fromObject(associatedMember),
                (Bool) TypeBool.BOOLEAN.fromObject(securityEnable));
    }

    public MACOrphanResponse(UInt orphanAddress, UInt shortAddress, Bool associatedMember, Bool securityEnable) {
        super("macOrphanResponse", StackEventType.LME_TYPE);
        if (orphanAddress == null) {
            throw new NullPointerException("orphanAddress is null");
        }
        if (shortAddress == null) {
            throw new NullPointerException("shortAddress is null");
        }
        if (associatedMember == null) {
            throw new NullPointerException("associatedMember is null");
        }
        if (securityEnable == null) {
            throw new NullPointerException("securityEnable is null");
        }
        if (associatedMember.isInvalid()) {
            throw new IllegalArgumentException("invalid associatedMember");
        }
        if (securityEnable.isInvalid()) {
            throw new IllegalArgumentException("invalid securityEnable");
        }
        this.orphanAddress = orphanAddress.convert(TypeUInt.UINT_64);
        this.shortAddress = shortAddress.convert(TypeUInt.UINT_16);
        this.associatedMember = associatedMember;
        this.securityEnable = securityEnable;
    }

    public UInt getOrphanAddressType() {
        return orphanAddress;
    }

    public UInt getShortAddressType() {
        return shortAddress;
    }

    public Bool getAssociatedMemberType() {
        return associatedMember;
    }

    public Bool getSecurityEnableType() {
        return securityEnable;
    }

    public Long getOrphanAddress() {
        return (Long) orphanAddress.toObject();
    }

    public Short getShortAddress() {
        return (Short) shortAddress.toObject();
    }

    public Boolean getAssociatedMember() {
        return (Boolean) associatedMember.toObject();
    }

    public Boolean getSecurityEnable() {
        return (Boolean) securityEnable.toObject();
    }

    public byte getCode() {
        return CODE;
    }

    public int getSize(RadioMACStackLayer layer) {
        return 11;
    }

    public void serialize(ByteBuffer bb, RadioMACStackLayer layer) {
        ByteUtils.ensureNotNull(bb);
        BitmapEditor be = new BitmapEditor(TypeBitmap.BITMAP_8);
        be.setBit(0, associatedMember.toObject() == Boolean.TRUE);
        be.setBit(1, securityEnable.toObject() == Boolean.TRUE);
        orphanAddress.serialize(bb);
        shortAddress.serialize(bb);
        be.create().serialize(bb);
    }

    public String toString() {
        return getName() + '(' + orphanAddress + ',' + shortAddress + ',' +
                associatedMember + ',' + securityEnable + ')';
    }
}
